package com.LockCondition;

import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁的运用
 */
public class ReadWriteLockTest {
    public static void main(String[] args) throws InterruptedException {
      final Queue3 g3=new Queue3();
      for(int i=0;i<3;i++)
      {
          new Thread(){
              public void  run(){
                  while (true){
                      g3.get();  //========================================读
                  }
              }
          }.start();
          new Thread(){
              public void  run(){
                  while (true){
                      g3.put(new Random().nextInt(10000));  //=====写
                  }
              }
          }.start();
      }
    }
}
class Queue3{
    private Object data=null;//共享数据，只能由一个线程能写数据，但可以有多个线程去读
    ReadWriteLock rw1=new ReentrantReadWriteLock();
    public void get(){
        rw1.readLock().lock();//================加上读锁
        // 为什么要加读锁，如果在读的过程中判断逻辑符合某种条件后需要去更改，则需要加入写锁，
        // 如果不加读锁，则其他线程进入也进行修改会出现问题，写锁挂了之后挂读锁就会降级成更新锁（读写锁）
        try {
            System.out.println(Thread.currentThread().getName()+"加上==读==锁");
            Thread.sleep((long)(Math.random()*1000));
            System.out.println(Thread.currentThread().getName()+"释放==读==锁");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            rw1.readLock().unlock();
        }
    }
   public void put(Object data){
        rw1.writeLock().lock();//================加上写锁
       try {
           System.out.println(Thread.currentThread().getName()+"加上==写==锁"+data);
           Thread.sleep((long)(Math.random()*1000));
           System.out.println(Thread.currentThread().getName()+"释放==写==锁"+data);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }finally {
           rw1.writeLock().unlock();
       }
   }


}